package com.jichangxiu.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.jichangxiu.common.utils.ConvertUtils;
import com.jichangxiu.system.entity.bo.SysRoleBo;
import com.jichangxiu.system.entity.bo.SysRoleMenuBo;
import com.jichangxiu.system.entity.dto.SysRoleMenuDto;
import com.jichangxiu.system.entity.dto.edit.EditSysRole;
import com.jichangxiu.system.entity.po.SysRoleMenu;
import com.jichangxiu.system.mapper.SysRoleMenuMapper;
import com.jichangxiu.system.service.SysRoleMenuService;
import com.jichangxiu.framework.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * SysRoleMenuServiceImpl:
 *
 * @author JiChangXiu
 * @create 2024-06-28 13:44:41
 */
@Slf4j
@Service
public class SysRoleMenuServiceImpl extends MPJBaseServiceImpl<SysRoleMenuMapper, SysRoleMenu> implements SysRoleMenuService {

    /**
     * 增加 / 修改 / 删除 角色菜单关联列表
     *
     * @param editSysRole        系统角色
     * @param sysRoleMenuDtoList 角色菜单关联对象列表
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addOrDelOrEdit(EditSysRole editSysRole, List<SysRoleMenuDto> sysRoleMenuDtoList) {
        SysRoleBo sysRoleBo = ConvertUtils.convert(editSysRole, SysRoleBo.class);
        // 角色和菜单的关联关系
        boolean b1 = true;
        boolean b2 = true;
        // 前端传来的角色菜单关联关系
        List<String> menuIdList = editSysRole.getMenuIdList();
        // 本次要新增的角色菜单关联关系
        List<SysRoleMenu> addSysRoleMenus = new ArrayList<>();
        // 本次要删除的角色菜单关联关系
        List<String> deleteRoleMenuIds = new ArrayList<>();
        if (ObjectUtil.isEmpty(menuIdList) && ObjectUtil.isEmpty(sysRoleMenuDtoList)) {
            // 如果两者都是空的则什么都不做
            log.info("本次无需操作");
        } else if (ObjectUtil.isNotEmpty(menuIdList) && ObjectUtil.isNotEmpty(sysRoleMenuDtoList)) {
            // 如果两者都不是空的
            for (String menuId : menuIdList) {
                // 当前菜单在数据库中是否存在，这里的判断值 默认不存在
                boolean flag = false;
                for (SysRoleMenuDto sysRoleMenuDto : sysRoleMenuDtoList) {
                    if (menuId.equals(sysRoleMenuDto.getMenuId())) {
                        // 代表当前菜单在数据库中已经存在
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    // 到上个循环结束还不存在，则证明当前菜单在数据库中不存在，需要录入数据库中
                    addSysRoleMenus.add(SysRoleMenu.builder().roleId(sysRoleBo.getId()).menuId(menuId).tenantId(SecurityUtils.getTenantId()).build());
                }
            }
            // 循环数据库中的值在页面传来的 List 中是否存在，如果不存在，则代表当前值被用户删除
            for (SysRoleMenuDto sysRoleMenuDto : sysRoleMenuDtoList) {
                // 默认不存在
                boolean flag = false;
                for (String menuId : menuIdList) {
                    if (sysRoleMenuDto.getMenuId().equals(menuId)) {
                        // 存在
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                    // 一直到上个循环结束，还是不存在，则证明当前数据库值已被用户删除
                    deleteRoleMenuIds.add(sysRoleMenuDto.getId());
            }
        } else if (ObjectUtil.isEmpty(menuIdList) && ObjectUtil.isNotEmpty(sysRoleMenuDtoList)) {
            // 页面传过来是空的，则需要把数据库中所有已经存在的数据全部删除
            sysRoleMenuDtoList.forEach(sysRoleMenuDto -> deleteRoleMenuIds.add(sysRoleMenuDto.getId()));
        } else if (ObjectUtil.isNotEmpty(menuIdList) && ObjectUtil.isEmpty(sysRoleMenuDtoList)) {
            // 如果页面传过来的不是空的，而数据库中尚未保存数据，则将页面传过来的全部保存
            menuIdList.forEach(menuId -> addSysRoleMenus.add(SysRoleMenu.builder().roleId(sysRoleBo.getId()).menuId(menuId).tenantId(SecurityUtils.getTenantId()).build()));
        }
        if (ObjectUtil.isNotEmpty(addSysRoleMenus))
            b1 = saveBatch(addSysRoleMenus);
        if (ObjectUtil.isNotEmpty(deleteRoleMenuIds))
            b2 = removeBatchByIds(deleteRoleMenuIds);
        return b1 && b2;
    }

    /**
     * 根据租户ID和用户ID查询角色菜单关联
     *
     * @param tenantId   租户ID
     * @param userIdList 用户ID列表
     * @return 角色菜单关联列表
     */
    @Override
    public List<SysRoleMenuBo> listsByUserId(String tenantId, List<String> userIdList) {
        return baseMapper.listsByUserId(tenantId, userIdList);
    }

}